<?php

namespace youmbe\media;

use Yii;
use Imagine\Image\Box;
use Imagine\Image\ImageInterface;
use Imagine\Image\ManipulatorInterface;
use Imagine\Image\Point;
use Imagine\Image\Palette\RGB;
use yii\base\InvalidParamException;
use yii\helpers\ArrayHelper;
use yii\helpers\FileHelper;
use Imagine\Exception\RuntimeException;

/**
 * Image implements most commonly used image manipulation functions using the [Imagine library](http://imagine.readthedocs.org/).
 *
 * Example of use:
 *
 * ```php
 * // generate a thumbnail image
 * Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)
 *     ->save(Yii::getAlias('@runtime/thumb-test-image.jpg'), ['quality' => 50]);
 * ```
 *
 * @author Antonio Ramirez <amigo.cobos@gmail.com>
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class Image extends \yii\imagine\BaseImage {

    public static $defautFont = '@common/data/fonts/simhei.ttf';

    /**
     * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2.
     * @param string|resource|ImageInterface $image either ImageInterface, resource or a string containing file path
     * @param int $margin the frame size to add around the image
     * @param string $color the frame color
     * @param int $alpha the alpha value of the frame.
     * @return ImageInterface
     */
    public static function buildCover($image, $name, $path) {
        ini_set("memory_limit", "256M");
        $img = self::ensureImageInterfaceInstance($image);
        $img = self::autorotate($img);
        $img = self::thumbnail($img, 136, 179, ManipulatorInterface::THUMBNAIL_FLAG_UPSCALE);
        $img = self::frame2($img, [
            'width' => 675,
            'height' => 420,
            'margin' => [34, 29],
            'alpha' => 0,
        ]);
        $img = Image::boxtext($img, $name, Yii::getAlias(self::$defautFont), [102, 202], [
            'size' => 14,
            'valign' => 'bottom',
        ]);
        $savepath = Yii::getAlias($path);
        FileHelper::createDirectory(dirname($savepath));
        try {
            $img->save($savepath);
        } catch (RuntimeException $exc) {
            Yii::error($exc->getMessage(), __METHOD__);
            return false;
        }
        return true;
    }

    /**
     * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2.
     * @param string|resource|ImageInterface $image either ImageInterface, resource or a string containing file path
     * @param int $margin the frame size to add around the image
     * @param string $color the frame color
     * @param int $alpha the alpha value of the frame.
     * @return ImageInterface
     */
    public static function frame2($image, array $options = []) {
        $img = self::ensureImageInterfaceInstance($image);

        $left = ArrayHelper::getValue($options, 'margin.0', 0);
        $top = ArrayHelper::getValue($options, 'margin.1', 0);
        $bgcolor = ArrayHelper::getValue($options, 'bgcolor', '666');
        $alpha = ArrayHelper::getValue($options, 'alpha', 100);
        $width = ArrayHelper::getValue($options, 'width', 100);
        $height = ArrayHelper::getValue($options, 'height', 100);

        $pasteTo = new Point($left, $top);

        $palette = new RGB();
        $color = $palette->color($bgcolor, $alpha);

        $box = new Box($width, $height);
        $finalImage = static::getImagine()->create($box, $color);
        $finalImage->paste($img, $pasteTo);

        return $finalImage;
    }

    /**
     * Draws a text string on an existing image.
     * @param string|resource|ImageInterface $image either ImageInterface, resource or a string containing file path
     * @param string $text the text to write to the image
     * @param string $fontFile the file path or path alias
     * @param array $start the starting position of the text. This must be an array with two elements representing `x` and `y` coordinates.
     * @param array $fontOptions the font options. The following options may be specified:
     *
     * - color: The font color. Defaults to "fff".
     * - size: The font size. Defaults to 12.
     * - angle: The angle to use to write the text. Defaults to 0.
     *
     * @return ImageInterface
     * @throws InvalidParamException if `$fontOptions` is invalid
     */
    public static function boxtext($image, $text, $fontFile, array $start = [0, 0], array $fontOptions = []) {
        if (!isset($start[0], $start[1])) {
            throw new InvalidParamException('$start must be an array of two elements.');
        }

        $fontSize = ArrayHelper::getValue($fontOptions, 'size', 12);
        $align = ArrayHelper::getValue($fontOptions, 'align', 'center');
        $valign = ArrayHelper::getValue($fontOptions, 'valign', 'middle');
        $fontColor = ArrayHelper::getValue($fontOptions, 'color', 'fff');
        $fontAngle = ArrayHelper::getValue($fontOptions, 'angle', 0);

        $palette = new RGB();
        $color = $palette->color($fontColor);

        $img = self::ensureImageInterfaceInstance($image);
        $font = static::getImagine()->font(Yii::getAlias($fontFile), $fontSize, $color);

        $box = $font->box($text);
        $d_w = $box->getWidth();
        $d_h = $box->getHeight();
        list($x, $y) = $start;

        if ($align == 'right') {
            $x -= $d_w;
        } elseif ($align == 'center') {
            $x -= $d_w / 2;
        }

        if ($valign == 'bottom') {
            $y -= $d_h;
        } elseif ($valign == 'middle') {
            $y -= $d_h / 2;
        }

        $img->draw()->text($text, $font, new Point($x, $y), $fontAngle);

        return $img;
    }

}
